package com.cs.framework.web.context;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.springframework.core.type.filter.AnnotationTypeFilter;

import com.cs.framework.common.util.ReflectUtils;
import com.cs.framework.common.util.StringUtils;
import com.cs.framework.common.util.ReflectUtils.LoopClassMethodDeal;
import com.cs.framework.core.context.Application;
import com.cs.framework.core.context.CoreModule;
import com.cs.framework.web.annotation.Action;
import com.cs.framework.web.annotation.Mapping;
import com.cs.framework.web.handler.HandlerMethod;

/**
 * Web模块上下文
 * 
 * @author hedongzhou
 * 
 */
public class WebModule extends CoreModule {

	/**
	 * 存放访问Action方法的映射信息
	 */
	private Map<String, HandlerMethod> methodMap = new HashMap<String, HandlerMethod>();

	public WebModule(Application application, String moduleId, String packagePath) {
		super(application, moduleId, packagePath);

		this.scanner.addIncludeFilter(new AnnotationTypeFilter(Action.class));
	}

	/**
	 * 初始化
	 */
	public void init() {
		super.init();

		// 初始化Action
		initAction();
	}

	/**
	 * 初始化Action
	 */
	protected void initAction() {
		Map<String, Object> actionMap = this.getBeansWithAnnotation(Action.class);
		Set<String> actionIdSet = actionMap.keySet();

		for (String actionId : actionIdSet) {
			Object actionBean = actionMap.get(actionId);

			final Map<String, Method> tempMethodMap = new HashMap<String, Method>();

			ReflectUtils.loopClassMethod(actionBean.getClass(), new LoopClassMethodDeal() {
				public boolean deal(Method method) {
					String name = null;
					Mapping mapping = method.getAnnotation(Mapping.class);

					if (mapping != null) {
						name = mapping.value();

						if (StringUtils.isBlank(name)) {
							name = method.getName();
						}

						tempMethodMap.put(name, method);
					}

					return true;
				}
			});

			Set<Entry<String, Method>> tempMethodSet = tempMethodMap.entrySet();
			for (Entry<String, Method> entry : tempMethodSet) {
				// 方法名称
				String method = entry.getKey();
				// 获取方法
				Method actionMethod = entry.getValue();

				// 保存映射信息
				HandlerMethod handlerMethod = new HandlerMethod();
				handlerMethod.setModule(this);
				handlerMethod.setActionBean(actionBean);
				handlerMethod.setActionMethod(actionMethod);
				methodMap.put(getActionMethodUrl(moduleId, actionId, method), handlerMethod);
			}
		}
	}

	/**
	 * 获取访问Action方法的映射信息
	 * 
	 * @return
	 */
	public Map<String, HandlerMethod> getMethodMap() {
		return methodMap;
	}

	/**
	 * 获取Action方法的访问URL
	 * 
	 * @param moduleId
	 *            模块ID
	 * @param actionId
	 *            Action请求ID
	 * @param method
	 *            Action请求方法
	 * @return
	 */
	private String getActionMethodUrl(String moduleId, String actionId, String method) {
		return "/" + moduleId + "/" + actionId + "/" + method;
	}

}
